﻿#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;


Mat src, dst1, dst2, dst3, dst4, dst5, dst6;
int BoxFilterValue = 6;
int MeanFilterValue = 10;
int GaussianFilterValue = 6;
int MedianFilterValue = 10;
int BilateralFilterValue = 10;
int TrackBarValue = 0;
int ElementSize = 3;

static void BoxFilter(int, void*);//方框滤波线性是均值滤波的爸爸
static void MeanFilter(int, void*);//均值滤波线性核窗口内输入图像对应像素的平均值
static void GaussianFilter(int, void*);//高斯滤波线性高斯函数
static void MedianFilter(int, void*);//中值滤波非线性领域灰度值的中值
static void BilateralFilter(int, void*);//双边滤波非线性比高斯滤波多了一个高斯方差
void Process();
static void TrackBarChange(int, void*);
static void ElementSizeChange(int, void*);
/* morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel)
 开运算    dst=open(src,element)=dilate(erodre) MORPH_OPEN
 闭运算    dst=close(src,element)=erode(dilate(src,element)) MORPH_CLOSE
 形态学梯度 dst=morph-grad(src,element)=dilate(src,element)-erode(src,element)
 顶帽      dst=tophat(src,element)=src-open(src,element)  MORPH_TOPHAT
 黑帽      dst=blackhat(src,element)=close(src,element)-src   MORPH_BLACKHAT
 */

int main(int a, char** p)
{

	/*Mat srcImag = imread("2.jpg"), grayImag, threImag, closeImag;
	cvtColor(srcImag, grayImag, CV_BGR2GRAY);
	GaussianBlur(grayImag, grayImag, Size(15, 15), 0);
	threshold(grayImag, threImag, 150, 255, THRESH_BINARY);
	morphologyEx(threImag, closeImag, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(15, 15)));
	morphologyEx(closeImag, closeImag, MORPH_OPEN, getStructuringElement(MORPH_RECT, Size(11, 11)));
	dilate(closeImag, closeImag, getStructuringElement(MORPH_RECT, Size(15, 15)));
	Canny(closeImag, closeImag, 10, 100);*/

	src = imread("lena.png");
	vector<Mat> channels;
	split(src, channels);
	Mat chB = channels.at(0);
	Mat chG = channels.at(1);
	Mat chR = channels.at(2);
	Mat mergeImag;
	Mat box;
	blur(src, box, Size(3, 3));
	merge(channels, mergeImag);



	dst1 = src.clone();
	dst2 = src.clone();
	dst3 = src.clone();
	dst4 = src.clone();
	dst5 = src.clone();
	dst6 = src.clone();

	namedWindow("src");
	imshow("src", src);

	namedWindow("BoxFilter");
	createTrackbar("Value:", "BoxFilter", &BoxFilterValue, 40, BoxFilter);
	BoxFilter(BoxFilterValue, 0);

	namedWindow("MeanFilter");
	createTrackbar("Value:", "MeanFilter", &MeanFilterValue, 40, MeanFilter);
	MeanFilter(MeanFilterValue, 0);

	namedWindow("GaussianFilter");
	createTrackbar("Value:", "GaussianFilter", &GaussianFilterValue, 30, GaussianFilter);
	GaussianFilter(GaussianFilterValue, 0);

	namedWindow("MedianFilter");
	createTrackbar("Value:", "MedianFilter", &MedianFilterValue, 50, MedianFilter);
	MedianFilter(MedianFilterValue, 0);

	namedWindow("BilateralFilter");
	createTrackbar("Value:", "BilateralFilter", &BilateralFilterValue, 50, BilateralFilter);
	BilateralFilter(BilateralFilterValue, 0);

	/*Mat element = getStructuringElement(MORPH_ELLIPSE, Size(2 * ElementSize + 1, 2 * ElementSize + 1), Point(ElementSize, ElementSize));
	erode(src, dst6, element);

	namedWindow("Enrode||Dilate");
	createTrackbar("Enrode Dilate", "Enrode||Dilate", &TrackBarValue, 1, TrackBarChange);
	createTrackbar("Size", "Enrode||Dilate", &ElementSize, 21, ElementSizeChange);

	imshow("Enrode||Dilate", dst6);*/

	waitKey(0);
	return 0;
}

static void BoxFilter(int, void*)
{
	boxFilter(src, dst1, -1, Size(BoxFilterValue + 1, BoxFilterValue + 1));
	imshow("BoxFilter", dst1);

}

static void MeanFilter(int, void*)
{
	blur(src, dst2, Size(MeanFilterValue + 1, MeanFilterValue + 1), Point(-1, -1));
	imshow("MeanFilter", dst2);

}

static void GaussianFilter(int, void*)
{
	GaussianBlur(src, dst3, Size(2 * GaussianFilterValue + 1, 2 * GaussianFilterValue + 1), 0, 0);
	imshow("GaussianFilter", dst3);

}

static void MedianFilter(int, void*)
{
	medianBlur(src, dst4, 2 * MedianFilterValue + 1);
	imshow("MedianFilter", dst4);

}

static void BilateralFilter(int, void*)
{
	bilateralFilter(src, dst5, BilateralFilterValue, BilateralFilterValue * 2, BilateralFilterValue / 2);
	imshow("BilateralFilter", dst5);

}
void TrackBarChange(int, void*)
{
	Process();

}

void ElementSizeChange(int, void*)
{
	Process();

}

void Process()
{
	Mat element = getStructuringElement(MORPH_ELLIPSE, Size(2 * ElementSize + 1, 2 * ElementSize + 1), Point(ElementSize, ElementSize));
	if (TrackBarValue == 0)
	{
		erode(src, dst6, element);
	}
	else
	{
		dilate(src, dst6, element);
	}
	imshow("Enrode||Dilate", dst6);

}